<template>
  <div class="ai-3d-generator">
    <!-- 顶层加载遮罩（取消默认常显，仅在全局需要时使用） -->
    <LoadingAnimation 
      v-if="false" 
      :progress="generationProgress"
    />
    
    <!-- 主要内容区域 -->
    <div class="main-content" :class="{ 'generating': isGenerating }">
      <!-- 左侧：提示词输入区域 -->
      <div class="input-panel">
        <PromptInput 
          :is-generating="isGenerating"
          @generate="handleGenerate"
        />
      </div>
      
      <!-- 右侧：3D模型显示区域 -->
      <div class="viewer-panel">
        <div class="viewer-header">
          <h3>3D模型预览</h3>
          <div class="viewer-controls" v-if="currentModelUrl">
            <button @click="resetCamera" class="control-btn">
              <span>🔄</span>
              重置视角
            </button>
            <button @click="toggleFullscreen" class="control-btn">
              <span>⛶</span>
              全屏
            </button>
            <button @click="downloadModel" class="control-btn" v-if="currentModelUrl">
              <span>⬇️</span>
              下载
            </button>
          </div>
        </div>

        <!-- 有效期提示 -->
        <div v-if="currentModelUrl && !isGenerating" class="expire-tip">
          <span class="tip-icon">⏰</span>
          该模型链接有效期仅为24小时，请尽快下载保存。
        </div>
        
        <div class="viewer-container">
          <!-- 右侧局部等待层：仅在点击生成后显示，页面初始不显示 -->
          <div v-if="isGenerating && !currentModelUrl" class="viewer-waiting-overlay">
            <div class="viewer-waiting-spinner"></div>
            <p class="viewer-waiting-text">AI正在生成您的3D模型，请耐心等待...</p>
            <p class="viewer-waiting-subtext">这通常需要1-3分钟，我们会自动更新进度</p>
          </div>
          <ModelViewer 
            ref="modelViewer"
            :model-data="currentModelData"
            @model-loaded="onModelLoaded"
            @model-error="onModelError"
          />
          
          <!-- ZIP文件提示（仅当无法显示3D模型时显示） -->
          <div v-if="currentModelUrl && currentModelUrl.includes('.zip') && currentModelData.type !== 'OBJ'" class="zip-file-notice">
            <div class="zip-icon">📦</div>
            <h3>模型文件已生成</h3>
            <p>您的3D模型已打包为ZIP文件，请点击下载按钮获取文件</p>
            <p class="zip-subtext">下载后解压ZIP文件即可查看3D模型</p>
          </div>
          
          <!-- 空状态提示 -->
          <div v-if="!currentModelUrl && !isGenerating" class="empty-state">
            <div class="empty-icon">🎨</div>
            <h3>开始创建您的3D模型</h3>
            <p>在左侧输入描述，AI将为您生成精美的3D模型</p>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 任务通知组件 -->
    <TaskNotification 
      :notification="taskNotification"
      :show="showTaskNotification"
      @close="closeTaskNotification"
    />
  </div>
</template>

<script>
import PromptInput from '@/components/PromptInput.vue'
import ModelViewer from '@/components/ModelViewer.vue'
import LoadingAnimation from '@/components/LoadingAnimation.vue'
import TaskNotification from '@/components/TaskNotification.vue'
import { modelAPI } from '@/services/api'
import webSocketService from '@/services/websocket'
import { mapGetters } from 'vuex'

export default {
  name: 'HomeView',
  components: {
    PromptInput,
    ModelViewer,
    LoadingAnimation,
    TaskNotification
  },
  computed: {
    ...mapGetters(['currentUser'])
  },
  data() {
    return {
      isGenerating: false,
      generationProgress: 0,
      currentModelUrl: '',
      currentModelData: {},
      currentTaskId: null,
      statusCheckInterval: null,
      errorMessage: '',
      taskNotification: {},
      showTaskNotification: false
    }
  },
  mounted() {
    // 组件挂载完成
    this.initWebSocket()
  },
  beforeUnmount() {
    this.clearStatusCheck()
    this.disconnectWebSocket()
  },
  methods: {
    async handleGenerate(requestData) {
      this.isGenerating = true
      this.generationProgress = 0
      this.errorMessage = ''
      this.currentModelUrl = ''
      this.currentModelData = {}
      
      try {
        if (requestData.generationMode === 'now') {
          // 立即生成模式
          let result
          if (requestData.inputMode === 'text') {
            result = await modelAPI.generateModel(requestData)
          } else {
            result = await modelAPI.generateModelFromImage(requestData)
          }
          
          if (!result.success) throw new Error(result.error)
          
          // 直接显示结果
          if (result.data && result.data.url) {
            this.currentModelUrl = result.data.url
            this.currentModelData = { url: result.data.url, type: requestData.resultFormat }
          }
        } else {
          // 异步生成模式
          let result
          if (requestData.inputMode === 'text') {
            result = await modelAPI.generateModelAsync(requestData)
          } else {
            result = await modelAPI.generateFromImageAsync(requestData)
          }
          
          if (!result.success) throw new Error(result.error)
          
          // 获取任务ID并开始轮询状态
          const taskData = result.data
          if (taskData && taskData.taskId) {
            this.currentTaskId = taskData.taskId
            this.startStatusCheck()
            
            // 显示提示信息
            alert(`任务已提交，任务ID: ${taskData.taskId.substring(0, 8)}...\n您可以在历史记录中查看进度`)
          } else {
            throw new Error('未获取到任务ID')
          }
        }
      } catch (error) {
        this.errorMessage = error.message || '请求失败'
        console.error('生成模型失败:', error)
      } finally {
        this.isGenerating = false
      }
    },
    
    startStatusCheck() {
      this.clearStatusCheck()
      this.statusCheckInterval = setInterval(async () => {
        if (!this.currentTaskId) return
        
        try {
          const result = await modelAPI.getTaskStatus(this.currentTaskId)
          if (result.success && result.data) {
            const task = result.data
                 if (task.status === 'DONE' && task.resultUrl) {
                   // 任务完成，设置模型数据
                   this.currentModelUrl = task.resultUrl
                   this.currentModelData = { url: task.resultUrl, type: 'GLB' }
                   this.isGenerating = false
                   this.clearStatusCheck()
                   
                   // 显示任务完成通知
                   this.showTaskCompletionNotification(task.taskId, 'DONE', '模型生成完成')
                 } else if (task.status === 'FAIL') {
                   // 任务失败
                   this.errorMessage = task.errorMessage || '生成失败'
                   this.isGenerating = false
                   this.clearStatusCheck()
                   
                   // 显示任务失败通知
                   this.showTaskCompletionNotification(task.taskId, 'FAIL', task.errorMessage || '生成失败')
                 }
            // RUN状态继续等待
          }
        } catch (error) {
          console.error('查询任务状态失败:', error)
        }
      }, 3000) // 每3秒查询一次
    },
    
    clearStatusCheck() {
      if (this.statusCheckInterval) {
        clearInterval(this.statusCheckInterval)
        this.statusCheckInterval = null
      }
    },
    
    onModelLoaded(gltf) {
      console.log('3D模型加载成功:', gltf)
      this.$emit('model-loaded', gltf)
    },
    
    onModelError(error) {
      console.error('3D模型加载失败:', error)
      this.errorMessage = '模型加载失败'
    },
    
    resetCamera() {
      // 触发ModelViewer组件重置相机
      this.$refs.modelViewer?.resetCamera()
    },
    
    toggleFullscreen() {
      // 实现全屏功能
      const viewer = document.querySelector('.viewer-container')
      if (viewer) {
        if (document.fullscreenElement) {
          document.exitFullscreen()
        } else {
          viewer.requestFullscreen()
        }
      }
    },
    
    downloadModel() {
      if (this.currentModelUrl) {
        const link = document.createElement('a')
        link.href = this.currentModelUrl
        // 根据文件类型设置下载文件名
        const fileExtension = this.currentModelData.type?.toLowerCase() || 'glb'
        const isZipFile = this.currentModelUrl.includes('.zip')
        const downloadName = isZipFile 
          ? `3d-model-${Date.now()}.zip`
          : `3d-model-${Date.now()}.${fileExtension}`
        link.download = downloadName
        link.click()
      }
    },
    
    showTaskCompletionNotification(taskId, status, message) {
      this.taskNotification = {
        taskId: taskId,
        status: status,
        message: message
      }
      this.showTaskNotification = true
    },
    
    closeTaskNotification() {
      this.showTaskNotification = false
      this.taskNotification = {}
    },
    
    // WebSocket相关方法
    initWebSocket() {
      if (this.currentUser && this.currentUser.id) {
        // 连接WebSocket
        webSocketService.connect(this.currentUser.id.toString())
        
        // 监听任务通知
        webSocketService.on('taskNotification', this.handleTaskNotification)
        
        // 监听连接状态
        webSocketService.on('connected', () => {
          console.log('WebSocket已连接，开始接收实时通知')
        })
        
        webSocketService.on('disconnected', () => {
          console.log('WebSocket连接已断开')
        })
        
        webSocketService.on('error', (error) => {
          console.error('WebSocket连接错误:', error)
        })
      }
    },
    
    disconnectWebSocket() {
      webSocketService.off('taskNotification', this.handleTaskNotification)
      webSocketService.disconnect()
    },
    
    handleTaskNotification(notification) {
      console.log('收到任务通知:', notification)
      
      // 显示通知
      this.taskNotification = {
        taskId: notification.taskId,
        status: notification.status,
        message: notification.message
      }
      this.showTaskNotification = true
      
      // 如果是当前正在轮询的任务，停止轮询
      if (this.currentTaskId === notification.taskId) {
        this.clearStatusCheck()
        this.isGenerating = false
        
        if (notification.status === 'DONE') {
          // 任务完成，刷新模型数据
          this.refreshModelData(notification.taskId)
        } else if (notification.status === 'FAIL') {
          // 任务失败
          this.errorMessage = notification.message || '生成失败'
        }
      }
    },
    
    async refreshModelData(taskId) {
      try {
        const result = await modelAPI.getTaskStatus(taskId)
        if (result.success && result.data && result.data.resultUrl) {
          this.currentModelUrl = result.data.resultUrl
          this.currentModelData = { url: result.data.resultUrl, type: 'GLB' }
        }
      } catch (error) {
        console.error('刷新模型数据失败:', error)
      }
    },
    
  }
}
</script>

<style scoped>
.ai-3d-generator {
  min-height: calc(100vh - 64px);
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  position: relative;
}

.main-content {
  display: flex;
  min-height: calc(100vh - 64px);
  transition: all 0.3s ease;
}

.main-content.generating {
  filter: blur(2px);
  pointer-events: none;
}

.input-panel {
  flex: 0 0 400px;
  background: white;
  border-right: 1px solid #e1e5e9;
  overflow-y: auto;
  max-height: 100vh;
}

.viewer-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #f8f9fa;
}

.viewer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 30px;
  background: white;
  border-bottom: 1px solid #e1e5e9;
}

.viewer-header h3 {
  margin: 0;
  color: #333;
  font-size: 20px;
}

.viewer-controls {
  display: flex;
  gap: 10px;
}

.control-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 8px 15px;
  border: 1px solid #e1e5e9;
  border-radius: 8px;
  background: white;
  color: #666;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 14px;
}

.control-btn:hover {
  border-color: #667eea;
  color: #667eea;
  transform: translateY(-1px);
}

.viewer-container {
  flex: 1;
  position: relative;
  background: #f0f0f0;
}

.viewer-waiting-overlay {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 5;
  text-align: center;
}

.viewer-waiting-spinner {
  width: 48px;
  height: 48px;
  border: 4px solid #e9ecef;
  border-top: 4px solid #667eea;
  border-radius: 50%;
  animation: viewerSpin 1s linear infinite;
  margin-bottom: 16px;
}

.viewer-waiting-text {
  margin: 0 0 6px 0;
  color: #333;
  font-size: 16px;
}

.viewer-waiting-subtext {
  margin: 0;
  color: #666;
  font-size: 14px;
}

@keyframes viewerSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.empty-state {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #666;
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 20px;
}

.empty-state h3 {
  font-size: 24px;
  margin: 0 0 10px 0;
  color: #333;
}

.empty-state p {
  font-size: 16px;
  margin: 0;
  opacity: 0.8;
}

.expire-tip {
  margin: 8px 0 0 0;
  padding: 8px 12px;
  background: #fff7e6;
  border: 1px solid #ffe7ba;
  color: #ad6800;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.tip-icon {
  font-size: 16px;
}

.zip-file-notice {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #666;
  background: #f8f9fa;
  padding: 30px;
  border-radius: 12px;
  border: 2px dashed #dee2e6;
  max-width: 400px;
}

.zip-icon {
  font-size: 64px;
  margin-bottom: 20px;
}

.zip-file-notice h3 {
  font-size: 24px;
  margin: 0 0 10px 0;
  color: #333;
}

.zip-file-notice p {
  font-size: 16px;
  margin: 0 0 8px 0;
  opacity: 0.8;
}

.zip-subtext {
  font-size: 14px !important;
  color: #999 !important;
  margin: 0 !important;
}


@media (max-width: 1024px) {
  .main-content {
    flex-direction: column;
  }
  
  .input-panel {
    flex: none;
    max-height: 50vh;
  }
  
  .viewer-panel {
    flex: 1;
    min-height: 50vh;
  }
}

@media (max-width: 768px) {
  .viewer-header {
    padding: 15px 20px;
  }
  
  .viewer-controls {
    flex-wrap: wrap;
  }
  
  .control-btn {
    font-size: 12px;
    padding: 6px 10px;
  }
  
}
</style>
